#include "CSpotLight.h"
#include "CMatrix.h"
#include <math.h>

CSpotLight::CSpotLight(): m_location(0, 0, 0), m_direction(1, 0, 0), m_cutOffAngle(1.57f), m_beamAngle(0.6f),
	m_attenuation(0, 0, 0)
{
	m_lightColor = CColor(1, 1, 1, 1);
	m_type = eSpotLight;
}

CSpotLight::CSpotLight(const CColor& color, const CVector3f& location, const CVector3f& direction, float cutOff,
					   float beam, const CVector3f& attenuation):m_location(location), m_direction(direction),
					   m_cutOffAngle(cutOff), m_beamAngle(beam), m_attenuation(attenuation)
{
	m_lightColor = color;
	m_direction.normalize();
	m_type = eSpotLight;
}

CSpotLight::~CSpotLight(){}

CColor CSpotLight::computeColor(const CRay& ray, float dist)const
{
	//calculate attenuation
	float A = 1;
	if(m_attenuation.norme2() != 0)
		A = m_attenuation.x + m_attenuation.y * dist + m_attenuation.z * dist * dist;

	//calculate itensity
	float theta = acos((-ray.getDirection()).dot(m_direction));
	theta = fabs(theta);

	float I = 1;
	if(theta > m_cutOffAngle)
		I = 0;
	else if (theta > m_beamAngle)
	{
		//I = (m_cutOffAngle - m_beamAngle) / m_cutOffAngle -(theta - m_beamAngle);
		I = (theta - m_cutOffAngle) / (m_beamAngle - m_cutOffAngle);
	}


	//return color
	return m_lightColor * I / A;
}

void CSpotLight::computeShadowRay(const CVector3f& point, CRay& shadowRay, float* distance)const
{
	//get a ray from the object to the light
	CVector3f L = m_location - point; //vector from the point of the object to the light
	*distance = L.norme();
	L.normalize();

	//to avoid intersection with itslef
	shadowRay.setOrigin(point + (L * 0.01f));
	shadowRay.setDirection(L);
}

void CSpotLight::applyViewMatrix(const CMatrix& view)
{
	
	m_location = m_location * view;

	CVector3f dirS = CVector3f(0, 0, 0) * view;
	CVector3f dirE = m_direction * view;
	m_direction = dirE - dirS;
	m_direction.normalize();
}